﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using Facebook;
using GermaneShanidze.Applications.Jokeri.LobbyServiceProxy;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Unity;
using Newtonsoft.Json.Linq;
using GermaneShanidze.Applications.Jokeri.Views;
using Microsoft.Practices.Prism.Events;
using GermaneShanidze.Applications.Jokeri.Events;

namespace GermaneShanidze.Applications.Jokeri.Modules
{
    public class MainModule : IModule
    {
        private readonly IUnityContainer Container;
        private readonly IEventAggregator EvAggregator;

        public void Initialize()
        {
            // define region manager
            RegionManager regionManager = this.Container.Resolve<RegionManager>();
            regionManager.RegisterViewWithRegion("ApplicationContentRegion", () => this.Container.Resolve<LobbyUsersView>());
            regionManager.RegisterViewWithRegion("FacebookStatusRegion", () => this.Container.Resolve<MyTableView>());
            regionManager.RegisterViewWithRegion("LobbyChatRegion", () => this.Container.Resolve<LobbyChatView>());
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="container"></param>
        /// <param name="regionManager"></param>
        public MainModule(IUnityContainer container, IEventAggregator evAggregator)
        {
            // Instancaite
            Container = container;
            EvAggregator = evAggregator;

            // Register singletons
            container.RegisterType<FacebookUserInfo>("standard", new ContainerControlledLifetimeManager());

            // Subscribe to FacebookUserIdPopulatedEvent
            EvAggregator.GetEvent<FacebookUserIdPopulatedEvent>().Subscribe(this.PoulateCurrentFacebookUserProfilePicture);

            // Initialise and load current facebook user account details
            PoulateCurrentFacebookUserName();
            
            //container.RegisterType<EditUserModalDialogView>("standard", new ContainerControlledLifetimeManager());
            //container.RegisterType<ModalView>("standard", new ContainerControlledLifetimeManager());
            
            //container.RegisterType<MessageBoxService>("standard", new ContainerControlledLifetimeManager());
        }

        private void PoulateCurrentFacebookUserName()
        {
            //Runs PoulateCurrentFacebookUserProfilePicture()
            //On completion

            //General Details
            var token = App.GetToken();
            if (!string.IsNullOrEmpty(token))
            {
                FacebookClient fbMe = new FacebookClient(token);
                fbMe.GetCompleted += new EventHandler<FacebookApiEventArgs>(fbMe_GetCompleted);

                // Call Async
                fbMe.GetAsync("/me");
            }
        }

        void fbMe_GetCompleted(object sender, FacebookApiEventArgs e)
        {
            // Runs PoulateCurrentFacebookUserProfilePicture()

            if (e.Error == null)
            {
                // Get basic profile data
                var result = (IDictionary<string, object>)e.GetResultData();
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    // Recover singleton Facbook User
                    FacebookUserInfo fui = Container.Resolve<FacebookUserInfo>("standard");
                    fui.UserId = long.Parse(result["id"].ToString());
                    fui.FirstName = result["first_name"].ToString();
                    fui.LastName = result["last_name"].ToString();

                    // Publish the Id populated event
                    EvAggregator.GetEvent<FacebookUserIdPopulatedEvent>().Publish(fui.UserId.ToString());
                });

                // Get profile picture url
                //PoulateCurrentFacebookUserProfilePicture();
            }
            else
            {
                // TODO: Need to let the user know there was an error
                //failedLogin();
            }
        }

        public void PoulateCurrentFacebookUserProfilePicture(string userId)
        {
            // Decalte and instanciate Faebook graph service
            WebClient client = new WebClient();
            Uri uri = new Uri("http://graph.facebook.com/" + userId + "/?fields=picture", UriKind.Absolute);
            client.DownloadStringCompleted += (s, a) =>
            {
                try
                {
                    if (a.Error == null)
                    {
                        //Recover Singleton FacebookUserInfo object
                        FacebookUserInfo lfui = Container.Resolve<FacebookUserInfo>("standard");

                        var json = a.Result;
                        JObject result = JObject.Parse(json);
                        lfui.ProfilePictureUrl = (string)result["picture"];
                    }
                    else
                    {
                        // Rerun the call
                        PoulateCurrentFacebookUserProfilePicture(userId);
                    }
                }
                catch
                {
                    //
                }
            };
            client.DownloadStringAsync(uri);
        }
    }
}